package br.edu.univas.locadoragraph.dao;

import java.util.ArrayList;
import java.util.List;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.graphdb.traversal.Traverser;
import org.neo4j.kernel.Traversal;

import br.edu.univas.locadoragraph.database.Connection;
import br.edu.univas.locadoragraph.database.Keys;
import br.edu.univas.locadoragraph.database.RelTypes;
import br.edu.univas.locadoragraph.to.ActorTO;
import br.edu.univas.locadoragraph.to.MovieTO;

public class TraversalGraph {
	private Connection conn;

	public TraversalGraph() {
		conn = Connection.getInstance();
		
	}
	
	public List<ActorTO> getMoviesActor(String user){
		System.out.println("Method: Get Actor movies");
		long start = System.currentTimeMillis();
		List<ActorTO> actors = new ArrayList<ActorTO>();
		GraphDatabaseService graph = conn.newGraphDatabase();
		Traverser traverser = null;
		Index<Node> index = graph.index().forNodes(Keys.INDEXUSER);
		
		Node node = index.get(Keys.USERKEY, user.toLowerCase()).getSingle();
		if (node != null) {
			TraversalDescription td = Traversal.description()
					.depthFirst()
					.relationships(RelTypes.WATCHED, Direction.OUTGOING)
					.relationships(RelTypes.SERVED, Direction.INCOMING)
					.evaluator(Evaluators.includeWhereLastRelationshipTypeIs(RelTypes.SERVED));
			traverser = td.traverse(node);
			for (Path path : traverser) {
				ActorTO actor = new ActorTO();
				actor.setName((String) path.endNode().getProperty(Keys.ACTORKEY));
				actor.setGender((String)path.endNode().getProperty("gender"));
				//actors.add(actor);
				System.out.println("Ator: " + actor.getName());
			}
		}
		//graph.shutdown();
		double total = System.currentTimeMillis() - start;
		System.out.println("Time: " + total / 1000);
		return actors;
	}
	public List<MovieTO> getEcommendationMovieForActor(String user){
		System.out.println("Method: get Ecommendation movie for Actor" );
		double start = System.currentTimeMillis();
		List<MovieTO> movies = new ArrayList<MovieTO>();
		GraphDatabaseService graph = conn.newGraphDatabase();
		Traverser traverser = null;
		Index<Node> index = graph.index().forNodes(Keys.INDEXUSER);
		
		Node node = index.get(Keys.USERKEY, user.toLowerCase()).getSingle();
		if (node != null) {
			TraversalDescription td = Traversal.description()
					.depthFirst()
					.relationships(RelTypes.WATCHED, Direction.OUTGOING)
					.relationships(RelTypes.SERVED, Direction.INCOMING)
					.relationships(RelTypes.SERVED, Direction.OUTGOING)
					.evaluator(Evaluators.atDepth(3));
			traverser = td.traverse(node);
			for (Path path : traverser) {
				MovieTO movieTO = new MovieTO();
				movieTO.setTitle((String) path.endNode().getProperty(Keys.MOVIEKEY));
				movieTO.setYear((int) path.endNode().getProperty("year"));
				movieTO.setSinopse((String) path.endNode().getProperty("sinopse"));
				System.out.println("Movie: " + movieTO.getTitle());
				movies.add(movieTO);
			}
		double total = System.currentTimeMillis() - start;
		System.out.println("Time: " + total/1000);
		}
	return movies;
		
	}
	public List<MovieTO> getEcommendationMovieForGender(String user) {
		System.out.println("Method: get Ecommendation movie for gender" );
		double start = System.currentTimeMillis();
		List<MovieTO> movies = new ArrayList<MovieTO>();
		GraphDatabaseService graph = conn.newGraphDatabase();
		Traverser traverser = null;
		Index<Node> index = graph.index().forNodes(Keys.INDEXUSER);
		
		Node node = index.get(Keys.USERKEY, user.toLowerCase()).getSingle();
		if (node != null) {
			TraversalDescription td = Traversal.description()
					.depthFirst()
					.relationships(RelTypes.WATCHED, Direction.OUTGOING)
					.relationships(RelTypes.BELONGS, Direction.OUTGOING)
					.relationships(RelTypes.BELONGS, Direction.INCOMING)
					.evaluator(Evaluators.atDepth(3));
			traverser = td.traverse(node);
			for (Path path : traverser) {
				MovieTO movieTO = new MovieTO();
				movieTO.setTitle((String) path.endNode().getProperty(Keys.MOVIEKEY));
				movieTO.setYear((int) path.endNode().getProperty("year"));
				movieTO.setSinopse((String) path.endNode().getProperty("sinopse"));
				System.out.println("Movie: " + movieTO.getTitle());
				movies.add(movieTO);
			}
		double total = System.currentTimeMillis() - start;
		System.out.println("Time: " + total/1000);
		}
	return movies;
	}
	
	public List<MovieTO> getEcommendationMovieForDirector(String user) {
		System.out.println("Method: get Ecommendation movie for gender" );
		double start = System.currentTimeMillis();
		List<MovieTO> movies = new ArrayList<MovieTO>();
		GraphDatabaseService graph = conn.newGraphDatabase();
		Traverser traverser = null;
		Index<Node> index = graph.index().forNodes(Keys.INDEXUSER);
		
		Node node = index.get(Keys.USERKEY, user.toLowerCase()).getSingle();
		if (node != null) {
			TraversalDescription td = Traversal.description()
					.depthFirst()
					.relationships(RelTypes.WATCHED, Direction.OUTGOING)
					.relationships(RelTypes.DIRECTED, Direction.INCOMING)
					.relationships(RelTypes.DIRECTED, Direction.OUTGOING)
					.evaluator(Evaluators.atDepth(3));
			traverser = td.traverse(node);
			for (Path path : traverser) {
				MovieTO movieTO = new MovieTO();
				movieTO.setTitle((String) path.endNode().getProperty(Keys.MOVIEKEY));
				movieTO.setYear((int) path.endNode().getProperty("year"));
				movieTO.setSinopse((String) path.endNode().getProperty("sinopse"));
				System.out.println("Movie: " + movieTO.getTitle());

				movies.add(movieTO);
			}
		double total = System.currentTimeMillis() - start;
		System.out.println("Time: " + total/1000);
		}
	return movies;
	}

}
